home *** CD-ROM | disk | FTP | other *** search
- /*
- SNEWS 1.91
-
- article - routines to read and display an article
-
-
- Copyright (C) 1991 John McCombs, Christchurch, NEW ZEALAND
- john@ahuriri.gen.nz
- PO Box 2708, Christchurch, NEW ZEALAND
-
- Modifications copyright (C) 1993 Daniel Fandrich
- <dan@fch.wimsey.bc.ca> or CompuServe 72365,306
-
- This program is free software; you can redistribute it and/or modify
- it under the terms of the GNU General Public License, version 1, as
- published by the Free Software Foundation.
-
- This program is distributed in the hope that it will be useful,
- but WITHOUT ANY WARRANTY; without even the implied warranty of
- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- GNU General Public License for more details.
-
- See the file COPYING, which contains a copy of the GNU General
- Public License.
-
-
- Source is formatted with a tab size of 4.
-
- */
-
-
- #include "defs.h"
- #include "snews.h"
- #include "pccharst.h"
- #include <alloc.h>
- #include <dir.h>
- #include <io.h>
- #include <ctype.h>
-
- enum char_sets current_char_set = DEFAULT_CHAR_SET;
- int active_code_page;
-
- static char *empty_line = "\n"; /* static empty line structure */
-
- void ReplyAddress(TEXT *tx, char *subject);
-
-
- /*-------------------- set up the global code page vars --------------------*/
- void select_code_page(void)
- {
- code_page_table = select_cp_table(active_code_page = get_code_page());
- }
-
- /*------------------------- read in an article -----------------------------*/
- TEXT *load_article(char *fnx, long offset)
- {
- /*
- * Open the file and read it. Save the author and organisation
- * fill in the structures
- */
-
- FILE *tmp_file;
- char buf[256], lnbuf[256], *p, *s, *token;
- TEXT *tx;
- LINE *ln, *lz;
- int ct, i;
-
- tx = NULL;
- ct = 0;
- current_char_set = DEFAULT_CHAR_SET;
-
- if ((tmp_file = flockopen(fnx, "rb")) != NULL) {
-
- fseek(tmp_file, offset, SEEK_SET);
-
- tx = xmalloc(sizeof(TEXT));
- tx->top = NULL;
- tx->start = NULL;
- strcpy(tx->follow_up, "");
- strcpy(tx->author, " ** none ** ");
- strcpy(tx->organisation, " ** none ** ");
-
- while (fgets(buf, sizeof(buf)-1, tmp_file) != NULL) {
-
- if (strncmp(buf, "@@@@END", 7) == 0) break;
-
- expand_tabs(buf, sizeof(buf)-1);
-
- /*
- * We now have a line of input. If the line is too long
- * it is wrapped at spaces or '!'. The lines of text are
- * stored in LINE structures
- */
- p = &buf[0];
- while (strlen(p) > 0) {
-
- strcpy(lnbuf, p);
- if (strlen(p) <= 80) {
- strcpy(lnbuf, p);
- *p = '\x00'; /* signal we're ready for a new line */
- } else {
- /* can we split the line at a nice spot (space , !) ? */
- p += 79;
- for (i = 79; i > 50; i--) {
- if ((lnbuf[i] == ' ') || (lnbuf[i] == '!') ||
- (lnbuf[i] == ','))
- break;
- p--;
- }
- /* can't split nicely -- split at the end of the line */
- if (i <= 50) {
- p += (79-i);
- i = 79;
- }
- lnbuf[i] = '\x00';
- }
-
- /* is it the first line - if so int the TEXT structure */
- if (ct == 0) {
- ln = xmalloc(sizeof(LINE));
- ln->last = NULL;
- tx->top = ln;
- } else {
- lz = ln;
- ln->next = xmalloc(sizeof(LINE));
- ln = ln->next;
- ln->last = lz;
- }
-
- ln->index = ct;
- if (lnbuf[0] == '\n') /* is the line empty? */
- ln->data = empty_line; /* yes, save malloc() overhead */
- else {
- ln->data = xmalloc(strlen(lnbuf)+1);
- strcpy(ln->data, lnbuf);
- }
-
- /* Find first line of body */
- if ((strlen(lnbuf) == 1) && (tx->start == NULL))
- tx->start = ln;
-
- ct++;
-
- /* save the header info */
- if ((tx->start == NULL) && (strnicmp("From:", lnbuf, 5) == 0)) {
- s = lnbuf + 5;
- while (*s && isspace(*s)) s++;
- *(s + WHO_LENGTH - 1) = '\0';
- strtok(strcpy(tx->author, s), "\n");
- }
-
- if ((tx->start == NULL) && ((strnicmp("Organisation:", lnbuf, 13) == 0) || (strncmp("Organization:", lnbuf, 13) == 0))) {
- s = lnbuf + 13;
- while (*s && isspace(*s)) s++;
- *(s + ORG_LENGTH - 1) = '\0';
- strtok(strcpy(tx->organisation, s), "\n");
- }
-
- if ((tx->start == NULL) && (strnicmp("Followup-To:", lnbuf, 12) == 0)) {
- s = lnbuf + 12;
- while (*s && isspace(*s)) s++;
- *(s + sizeof(tx->follow_up) - 1) = '\0';
- strtok(strcpy(tx->follow_up, s), "\n");
- }
-
- if ((tx->start == NULL) && (strnicmp("Content-Type:", lnbuf, 13) == 0)) {
- s = lnbuf + 13;
-
- while (*s && isspace(*s)) s++; /* kill leading spaces */
- token = strtok(s, " ;\n");
- while (token != NULL) {
- if (strnicmp("charset=", token, 8) == 0) {
- current_char_set = select_char_set(token+8);
- break;
- }
- token = strtok(NULL, " ;\n");
- }
- }
- }
-
- }
-
- ln->next = NULL;
- tx->lines = ct;
-
- fclose(tmp_file);
- }
-
- return(tx);
- }
-
-
-
- /*---------------------- deallocate article memory ------------------------*/
- void free_article(TEXT *t)
- {
-
- LINE *l, *k;
-
- l = t->top;
- while (l != NULL) {
- k = l;
- l = l->next;
- if (k->data != empty_line) /* don't free empty line pointer */
- free(k->data);
- free(k);
- }
-
- free(t);
- }
-
-
-
- /*---------------------------- read an article ----------------------------*/
- enum exit_codes read_article(ACTIVE *gp, TEXT *tx, char *subject, int a_ct, int of_ct)
- {
- /*
- * This routine allows the user to read an article
- */
-
- LINE *this, *tmp; /* current thread */
- enum exit_codes exit_code; /* why we are exiting the loop */
- char sub_tmp[80]; /* new subject line */
-
- int i, maxx;
-
- this = tx->start;
- if (this->next != NULL)
- this = this->next; /* skip over blank line */
- show_article(gp, tx, subject, this, a_ct, of_ct);
-
- exit_code = EX_CONT;
- while ((exit_code == EX_CONT) || (exit_code == EX_DUMMY)) {
-
- exit_code = EX_CONT;
- gotoxy(1,25);
- switch (get_any_key()) {
-
- case Fn1 :
- case '?' :
- case 'h' :
- show_help(HELP_ARTICLES);
- break;
-
- case Fn2 :
- show_values();
- break;
-
- case Fn3 :
- if (current_char_set++ == US_ASCII)
- current_char_set = 0;
- break;
-
- case Fn4 :
- pipe_article(tx, my_stuff.hotpipe);
- message("-- Done --");
- break;
-
- case UP_ARR :
- if (this->last != NULL) {
- this = this->last;
- gotoxy(1,TEXT_LINE+PAGE_LENGTH-1);
- delline();
- gotoxy(1,TEXT_LINE);
- insline();
- clreol();
- cputs(translate_line(this->data, current_char_set));
- show_percent((int) ((100L * (this==NULL ? tx->lines+1 : min((this->index) + PAGE_LENGTH, tx->lines+1))) / ((tx->lines) + 1)));
- }
- exit_code = EX_DUMMY;
- break;
-
- case DN_ARR :
- if (this->next != NULL &&
- (this->index + PAGE_LENGTH < tx->lines ||
- this->index <= tx->start->index)) {
- this = this->next;
- gotoxy(1,TEXT_LINE);
- delline();
- gotoxy(1,TEXT_LINE+PAGE_LENGTH-1);
- insline();
-
- tmp = this;
- for (i = 0; i < PAGE_LENGTH-1; i++) {
- tmp = tmp->next;
- if (tmp == NULL) break;
- }
-
- if (tmp)
- cputs(translate_line(tmp->data, current_char_set));
- show_percent((int) ((100L * (tmp==NULL ? tx->lines+1 : tmp->index)) / ((tx->lines) + 1)));
- }
- exit_code = EX_DUMMY;
- break;
-
- case 'b' :
- case PGUP :
- for (i = 0; i < PAGE_LENGTH-1; i++) {
- if (this->last == NULL) break;
- this = this->last;
- }
- break;
-
- case ' ' :
- case PGDN :
- if ( this->next == NULL )
- exit_code = EX_DUMMY;
- else {
- #ifndef ALTPAGING /* maintain reading place paging method */
- maxx = 0;
- if ((tx->lines - (this->index + PAGE_LENGTH)) > 0)
- maxx = PAGE_LENGTH - 1;
-
- #else /* don't show past end of article paging method */
- maxx = tx->lines - (this->index + PAGE_LENGTH);
- maxx = min(maxx, PAGE_LENGTH - 1);
- maxx = max(maxx, tx->start->index + 1 - this->index);
- #endif
-
- if ( maxx <= 0 )
- exit_code = EX_DUMMY;
- else
- for (i = 0; i < maxx; i++) {
- if (this->next == NULL) break;
- this = this->next;
- }
- }
- break;
-
- case 'R'-0x40 :
- case HOME :
- tmp = this;
- this = tx->start;
- if (this->next != NULL)
- this = this->next; /* skip over blank line */
- if (this == tmp)
- exit_code = EX_DUMMY;
- break;
-
- case END :
- tmp = this;
- this = tx->start;
- while (this->next != NULL)
- this = this->next;
- for (i = 0; i < PAGE_LENGTH-1; i++) {
- if (this->last == NULL) break;
- if (tx->start->next && this == tx->start->next)
- break;
- this = this->last;
- }
- if (this == tmp)
- exit_code = EX_DUMMY;
- break;
-
- case '[' :
- case '-' :
- case LEFT :
- exit_code = EX_PREVIOUS;
- break;
-
- case ']' :
- case RIGHT :
- exit_code = EX_NEXT;
- break;
-
- case cLEFT :
- exit_code = EX_PREVIOUS10;
- break;
-
- case cRIGHT :
- exit_code = EX_NEXT10;
- break;
-
- case 'v' :
- tmp = this;
- this = tx->top;
- if (this == tmp)
- exit_code = EX_DUMMY;
- break;
-
- case '/' :
- this = search_text(this);
- break;
-
- case 'p' :
- strcpy(sub_tmp, "");
- post(NULL, gp->group, sub_tmp);
- break;
-
- case 'f' :
- if (strnicmp(subject, "Re:", 3) != 0) {
- strcpy(sub_tmp, "Re: ");
- strcat(sub_tmp, subject);
- } else
- strcpy(sub_tmp, subject);
- if (strlen(tx->follow_up) == 0) {
- post(tx, gp->group, sub_tmp);
- } else if (stricmp(tx->follow_up, "poster") == 0) {
- reply_to_article(tx, sub_tmp);
- } else
- post(tx, tx->follow_up, sub_tmp);
- break;
-
- case 'r' :
- if (strnicmp(subject, "Re:", 3) != 0) {
- strcpy(sub_tmp, "Re: ");
- strcat(sub_tmp, subject);
- } else
- strcpy(sub_tmp, subject);
- reply_to_article(tx, sub_tmp);
- break;
-
- case 'R' :
- if (strnicmp(subject, "Re:", 3) != 0) {
- strcpy(sub_tmp, "Re: ");
- strcat(sub_tmp, subject);
- } else
- strcpy(sub_tmp, subject);
- ReplyAddress(tx, sub_tmp);
- break;
-
- case 'm' :
- mail_to_someone(tx);
- break;
-
- case 's' :
- save_to_disk(tx, NULL, FALSE);
- message("-- Done --");
- break;
-
- case 'w' :
- save_to_disk(tx, my_stuff.extract_file, TRUE);
- message("-- Done --");
- break;
-
- case '|' :
- pipe_article(tx, NULL);
- message("-- Done --");
- break;
-
- case 'x' :
- case 'X' :
- rot13(tx);
- break;
-
- case 'X'-0x40 :
- this = tx->start;
- if (this->next != NULL)
- this = this->next; /* skip over blank line */
- rot13(tx);
- break;
-
- case '!' :
- textbackground(BLACK); textcolor(LIGHTGRAY);
- cprintf("\r\n");
- spawnl(P_WAIT, getenv("COMSPEC"), getenv("COMSPEC"), NULL);
- break;
-
- case TAB :
- exit_code = EX_NEXT_UNREAD;
- break;
-
- case ENTER :
- exit_code = EX_NEXT;
- break;
-
- case '=' :
- case ESCAPE :
- exit_code = EX_QUIT;
- break;
-
- default :
- exit_code = EX_DUMMY;
- break;
- }
- if (exit_code == EX_CONT)
- show_article(gp, tx, subject, this, a_ct, of_ct);
- }
-
- return(exit_code);
- }
-
-
-
- /*--------------------- display a page of an article ------------------------*/
- void show_article(ACTIVE *gp, TEXT *tx, char *subject, LINE *this, int a_ct,
- int of_ct)
- {
- /*
- * This routine show a page of an article
- */
-
- int i;
- char buf[63];
-
- strcpy(buf, subject);
- buf[59] = '\x00';
-
- textbackground(textb); textcolor(textf);
- clrscr();
- textbackground(headb); textcolor(headf);
- clreol();
- cprintf("Group: %-53s Article:%3d of %3d\r\n",
- gp->group, a_ct, of_ct);
- clreol();
- cprintf("Subject: %-59s %4d lines\r\n",
- translate_header(buf, current_char_set), tx->lines);
- clreol();
- /* cprintf("From: %s; %s", translate_header(tx->author, current_char_set),
- translate_header(tx->organisation, current_char_set));*/
- cprintf("From: %s", translate_header(tx->author, current_char_set));
- command("ESC=select thread TAB=next unread ENTER=next F1=help");
-
- textbackground(textb); textcolor(textf);
-
- gotoxy(1, TEXT_LINE);
- for (i = 0; i < PAGE_LENGTH; i++) {
- gotoxy(1, i+TEXT_LINE);
- cputs(translate_line(this->data, current_char_set));
- this = this->next;
- if (this == NULL) break;
- }
-
- show_percent((int) ((100L * (this==NULL ? tx->lines+1 : this->index)) / ((tx->lines) + 1)));
- }
-
-
- /*-------------------- search for text in article body -------------------*/
- LINE *search_text(LINE *this)
- {
- char search_text[80];
- static char last_text[80] = {'\0'};
-
- message("Search for? ");
- if (*gets(search_text))
- strcpy(last_text, search_text);
- else
- strcpy(search_text, last_text);
- #ifdef AMATCH
- strlwr(search_text); /* lower case string for case insensitive search */
- #endif
-
- if (search_text[0])
- while (this->next) {
- this = this->next;
- #ifdef AMATCH
- if (amatch(search_text, strlwr(translate_line(this->data, current_char_set))))
- #else
- if (stristr(translate_line(this->data, current_char_set), search_text))
- #endif
- break;
- }
- message("");
- return this;
- }
-
-
- /*-------------------- show percentage through article -------------------*/
- void show_percent(int percent)
- {
- /*
- * This routine displays how far through an article we are
- */
-
- gotoxy(2,25);
- textbackground(msgb); textcolor(msgf);
- cprintf("%d%% ", percent);
- textbackground(textb); textcolor(textf);
- }
-
-
-
-
- /*-------------------------- save article --------------------------------*/
- int save_to_disk(TEXT *tx, char *save_name, int mailbox)
- {
- /*
- * This routine saves an article to disk, appending if necessary
- * If save_name is NULL, user is asked for a name
- * If save_name is not NULL, article is saved to the save_name file
- * If mailbox is nonzero, article is saved in mailbox format
- * Returns 0 if no error, 1 if error
- * (one anomaly -- if user elects not to append, 1 is returned)
- */
-
- FILE *tmp = NULL;
- LINE *ln;
- char fn[80];
- int ch;
-
- if (save_name == NULL) { /* save function */
- lmessage("Filename? ");
- gets(fn);
- } else /* extract function */
- strcpy(fn, save_name);
-
- if (!*fn) /* abort if no file name given */
- return 0;
-
- expand_filename(fn); /* expand ~/ in file name */
-
- if (access(fn, 0) == 0) { /* file exists -- should we append? */
- if (save_name) {
- if ((tmp = fopen(fn, "at")) == NULL) {
- message("*** Cannot open file for appending - "
- "press any key to continue ***");
- get_any_key();
- }
- } else {
- message("File exists - append (y/n)? ");
- while (((ch = tolower(getch())) != 'y') && (ch != 'n'));
- if (ch == 'y') {
- if ((tmp = fopen(fn, "at")) == NULL) {
- message("*** Cannot open file for appending - "
- "press any key to continue ***");
- get_any_key();
- }
- }
- }
-
- } else { /* file doesn't exist -- try to create it */
-
- /* make sure the file name given doesn't have bad characters */
- if ((strcspn(fn, " \"*+,;<=>?[]|\x7f\xe5") != strlen(fn)) ||
- ((tmp = fopen(fn, "wt")) == NULL)) {
- message("*** Cannot open file for output - press any key to continue ***");
- get_any_key();
- }
- }
-
- if (tmp != NULL) {
- if (mailbox) {
- fputs("\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01"
- "\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\n",tmp);
- }
-
- /* save article contents to disk */
- /* \n are stored in the ln->data structures so we don't need to
- write any others out */
- ln = tx->top;
- while (ln != NULL) {
- fputs(ln->data, tmp);
- ln = ln->next;
- }
- fclose(tmp);
- }
-
- return (tmp == NULL);
- }
-
-
- /*------------------- pipe article through a program ---------------------*/
- void pipe_article(TEXT *tx, char *prog_name)
- {
- /*
- * This routine saves an article to a temporary file.
- * If prog_name is NULL, user is asked for a program name and the article
- * is piped through that program.
- * If prog_name is not NULL, article is piped through that program.
- */
-
- char prog[129], cmd[129], temp[81];
- char *pipe;
-
- if (prog_name == NULL) { /* save function */
- lmessage("Pipe article through which program? ");
- gets(prog);
- } else /* extract function */
- strcpy(prog, prog_name);
-
- if (!*prog) /* abort if no program given */
- return;
-
- if (strchr(prog, '<')) {
- message("*** Cannot redirect input - press any key to continue ***");
- get_any_key();
- } else {
- sprintf(temp, "%spipe%04x.tmp", my_stuff.temp_str, getpid());
-
- strcpy(cmd, prog);
-
- /* if command contains %s, put file name there */
- if (strstr(cmd, "%s") != NULL) {
- sprintf(cmd, prog, temp);
-
- /* look for a second pipe in command and put the redirect in the right spot */
- } else if ((pipe = strchr(cmd, '|')) != NULL) {
- strcat(strcat(strcat(strcpy(pipe, " <"), temp), " "), strchr(prog, '|'));
-
- /* append file redirect to end of command */
- } else
- strcat(strcat(cmd, " <"), temp);
-
- if (!save_to_disk(tx, temp, FALSE)) { /* save article to temporary file */
- clrscr();
- system(cmd);
- unlink(temp);
- printf("\n\n");
- message("-- Press any key to continue --");
- get_any_key();
- }
-
- }
- }
-
-
- /*------------------- expand an alias to the email address ------------------*/
- char *expand_alias(char *author)
- {
- char buf[256];
- FILE *aliasfile;
- char *s;
-
- /*
- * Given a possible alias in author, search the alias file for a match
- * and return the full email address back in author.
- */
-
- if (*my_stuff.alias_file && (aliasfile = fopen(my_stuff.alias_file,"rt")) != NULL) {
- while (fgets(buf, sizeof(buf)-1, aliasfile) != NULL) {
- /* ignore comment line */
- if (buf[0] == ';' || buf[0] == '#' || isspace(buf[0]))
- continue;
-
- /* find matching alias */
- if (strnicmp(author, buf, strlen(author)) == 0) {
-
- /* skip over alias */
- s = strpbrk(buf," \t");
- while (*++s && isspace(*s))
- ;
-
- /* skip over name in quotes, if any */
- if (*s == '\"') {
- ++s;
- while (*s && (*s != '\"')) ++s;
- ++s;
- while (*s && (isspace(*s) || (*s == '<'))) ++s;
- }
-
- /* copy full name into the pointer given for the alias */
- if ((s = strtok(s, " >;\t\r\n")) != NULL)
- strcpy(author,s);
- break;
- }
- } /* while */
-
- fclose(aliasfile);
- } /* if */
-
- return author;
- }
-
-
- /*-------------------------- reply to article ---------------------------*/
- void reply_to_article(TEXT *tx, char *subject)
- {
- /*
- * Mail reply to article
- */
-
- #ifdef INCLUDE_SIG
- FILE *sig;
- char sig_fn[80];
- #endif
-
- FILE *tmp;
- LINE *ln;
- int ch;
- char fn[81];
- char buf[256];
- char author[WHO_LENGTH], msg_id[MSG_ID_LENGTH];
-
- sprintf(fn, "%srply%04x.tmp", my_stuff.temp_str, getpid());
-
- if ((tmp= fopen(fn, "wt")) != NULL) {
-
- strcpy(author, " ");
- get_his_stuff(tx, author, msg_id);
-
- /* add the quoted message */
- message("Quote article (y/n)? ");
- while (((ch = tolower(getch())) != 'y') && (ch != 'n'));
-
- if (ch == 'y') {
- fprintf(tmp, "In article %s you write:\n", msg_id);
- ln = tx->start;
- while (ln != NULL) {
- fprintf(tmp, ">%s", ln->data);
- ln = ln->next;
- }
- }
-
- #ifdef INCLUDE_SIG
- /* append the signature if there is one */
- strcpy(sig_fn, my_stuff.home);
- strcat(sig_fn, my_stuff.signature);
- if ((sig= fopen(sig_fn, "rt")) != NULL) {
- fprintf(tmp, "\n--\n");
- while (fgets(buf, 79, sig) != NULL)
- fputs(buf, tmp);
- fclose(sig);
- }
- #endif
- fclose(tmp);
-
- ch = 'e';
-
- /* NEW BIT includes send/abort/edit */
- while ((ch != 's') && (ch != 'a')) {
- if (ch == 'e') {
- sprintf(buf, my_stuff.editor, fn);
- system(buf);
- }
- clrscr();
- gotoxy(1,23);
- cprintf(" Mail reply addressed to: %s",author);
- sprintf(buf,"Mail reply: (S)end, (A)bort, or (E)dit again? (S/A/E):");
- message(buf);
- while (((ch = tolower(getch())) != 's') && (ch != 'a') && (ch != 'e'));
- gotoxy(1,24);
- }
-
- if (ch == 's') {
- sprintf(buf, "mail -s \"%s\" %s <%s", subject, author, fn);
- system(buf);
- }
- unlink(fn);
- message("-- Press any key to continue --");
- get_any_key();
-
- } else {
- message("*** Cannot open temp file - press any key to continue ***");
- get_any_key();
- }
-
- }
-
-
-
- /* ---------- (R)eply allowing specified address or alias ---------------- */
-
- void ReplyAddress(TEXT *tx, char *subject)
- {
- #ifdef INCLUDE_SIG
- FILE *sig;
- char sig_fn[80];
- #endif
-
- FILE *tmp;
- LINE *ln;
- int ch;
- char fn[81];
- char buf[256];
- char author[WHO_LENGTH], msg_id[MSG_ID_LENGTH];
-
- sprintf(fn, "%srply%04x.tmp", my_stuff.temp_str, getpid());
-
- if ((tmp= fopen(fn, "wt")) != NULL) {
-
- get_his_stuff(tx, author, msg_id);
-
- /* add the quoted message */
- message("Quote article (y/n)? ");
- while (((ch = tolower(getch())) != 'y') && (ch != 'n'));
-
- if (ch == 'y') {
- fprintf(tmp, "In article %s you write:\n", msg_id);
- ln = tx->start;
- while (ln != NULL) {
- fprintf(tmp, ">%s", ln->data);
- ln = ln->next;
- }
- }
-
- #ifdef INCLUDE_SIG
- /* append the signature if there is one */
- strcpy(sig_fn, my_stuff.home);
- strcat(sig_fn, my_stuff.signature);
- if ((sig= fopen(sig_fn, "rt")) != NULL) {
- fprintf(tmp, "\n--\n");
- while (fgets(buf, 79, sig) != NULL)
- fputs(buf, tmp);
- fclose(sig);
- }
- #endif
- fclose(tmp);
-
- lmessage("Send reply to whom (aliases allowed)? ");
- gets(author);
-
- if (*author) {
- expand_alias(author);
-
- ch = 'e';
- while ((ch != 's') && (ch != 'a')) {
- if (ch == 'e') {
- sprintf(buf, my_stuff.editor, fn);
- system(buf);
- }
- sprintf(buf,"Mail article: (S)end, (A)bort, or (E)dit again? (S/A/E):");
- message(buf);
- while (((ch = tolower(getch())) != 's') && (ch != 'a') && (ch != 'e'));
- gotoxy(1,24);
- }
- if (ch == 's') {
- sprintf(buf, "mail -s \"%s\" %s <%s", subject, author, fn);
- system(buf);
- }
- unlink(fn);
- message("-- Press any key to continue --");
- get_any_key();
-
- } else {
- unlink(fn);
- }
-
- } else {
- message("*** Cannot open temp file - press any key to continue ***");
- get_any_key();
- }
-
- }
-
-
-
- /*-------------------------- reply to article ---------------------------*/
- void mail_to_someone(TEXT *tx)
- {
- /*
- * Mail this article to someone
- */
-
-
- FILE *tmp;
- LINE *ln;
- int ch;
- char fn[MAXPATH+1];
- char buf[256], who[80];
-
- lmessage("Mail this article to (aliases allowed)? ");
- gets(who);
-
- if (*who) {
-
- sprintf(fn, "%srply%04x.tmp", my_stuff.temp_str, getpid());
- if ((tmp= fopen(fn, "wt")) != NULL) {
-
- expand_alias(who);
-
- fprintf(tmp, "Resent-From: %s@%s (%s)\n",
- my_stuff.user, my_stuff.my_domain, my_stuff.my_name);
- fprintf(tmp, "Resent-To: %s\n", who);
-
- ln = tx->top;
- while (ln != NULL) {
- fputs(ln->data, tmp);
- ln = ln->next;
- }
-
- fclose(tmp);
-
- message("Edit outgoing message (y/n)? ");
- while (((ch = tolower(getch())) != 'y') && (ch != 'n'));
- if (ch == 'y') {
- sprintf(buf, my_stuff.editor, fn);
- system(buf);
- }
-
- sprintf(buf, "Mail article to %s (y/n)? ", who);
- message(buf);
- while (((ch = tolower(getch())) != 'y') && (ch != 'n'));
- if (ch == 'y') {
- sprintf(buf, "rmail -t <%s", fn);
- system(buf);
- }
-
- unlink(fn);
-
- } else {
- message("*** cannot open temp file - press any key ***");
- get_any_key();
- }
- }
- }
-
-
- /*----------------------- find email address in line --------------------*/
-
- /*---------------------------------------------------------*/
- /* char *get_address() */
- /* */
- /* searches for the '@' char in internet addresses and */
- /* then extracts the word the '@' is in. The terminat- */
- /* ating characters are : ':' '<' '>' '(' ')' '"' '\t' */
- /* '\r' and '\n'; at which point it stops looking. */
- /* */
- /*---------------------------------------------------------*/
-
- char *get_address(char *buf, char *addr)
- {
- char *p , *c;
-
- /* search for the '@' or "at" that is in every Internet address */
-
- if ((p = strchr(buf,'@')) != NULL) {
- c = p;
- while (*p && (*p != ' ' &&
- *p != '\t' &&
- *p != ':' &&
- *p != '<' &&
- *p != '\"' &&
- *p != '(' )) {
- /* quite a few cases to check for */
- p--;
- }
-
- while (*c && (*c != ' ' &&
- *c != '\t' &&
- *c != ':' &&
- *c != '>' &&
- *c != '\"' &&
- *c != '\n' &&
- *c != '\r' &&
- *c != ')' )) {
- /* quite a few cases to check for */
- c++;
- }
- *c = '\0';
- strcpy(addr, ++p);
- return addr;
- }
-
- return NULL;
- }
-
- /*----------------------- get stuff off article header --------------------*/
-
- /*---------------------------------------------------------*/
- /* void get_his_stuff() */
- /* */
- /* obtains the address of the person in the passed arti- */
- /* cle, as well as the msgid. */
- /* */
- /*---------------------------------------------------------*/
- void get_his_stuff(TEXT *tx, char *author, char *msg_id)
- {
- /*
- * Retrieve the author and msg_id from the article
- */
-
- LINE *ln;
- char *p;
- char buf[256];
- char *null_name = " < no name > ";
-
- strcpy(author, null_name);
- strcpy(msg_id, " <none> ");
-
- ln = tx->top;
- while (ln != NULL) {
- strcpy(buf, ln->data);
- strtok(buf, " :\n\r"); /* skip over <header>: */
- p = strtok(NULL, " :\n\r"); /* skip over space */
- if (p != NULL) {
-
- if (strnicmp(ln->data, "Message-ID:", 11) == 0) {
- p = ln->data + 11; /* is this necessary? [df] */
- while (*p && isspace(*p))
- ++p;
- p = strtok(p, " :\n\r");
- if (p)
- strncpy(msg_id, p, MSG_ID_LENGTH-1);
- else
- strncpy(msg_id, ln->data + 11, MSG_ID_LENGTH-1);
- msg_id[MSG_ID_LENGTH-1] = '\0';
- }
-
- if ((strnicmp(ln->data, "From:", 5) == 0) && (strcmp(author, null_name) == 0)) {
- if (get_address(ln->data, author) == NULL) {
- strncpy(author, p, WHO_LENGTH-1);
- author[WHO_LENGTH-1] = '\0';
- }
- }
-
- if (strnicmp(ln->data, "Reply-To:", 5) == 0) {
- if (get_address(ln->data, author) == NULL) {
- strncpy(author, p, WHO_LENGTH-1);
- author[WHO_LENGTH-1] = '\0';
- }
- }
-
- } /* if */
-
- if (strlen(ln->data) < 2)
- break; /* we've found the start of the body */
- ln = ln->next;
- }
- }
-
- /*--------------------------- rot 13 the article ------------------------*/
- void rot13(TEXT *tx)
- {
- LINE *ln;
- int i, c;
-
-
- ln = tx->start;
-
- while (ln != NULL) {
- for (i = 0; i < strlen(ln->data); i++) {
- c = *((ln->data)+i);
- if ((c >= 'A') && (c <= 'Z')) {
- *((ln->data)+i) = (((c-'A') + 13) % 26) + 'A';
- } else {
- if ((c >= 'a') && (c <= 'z')) {
- *((ln->data)+i) = (((c-'a') + 13) % 26) + 'a';
- }
- }
- }
- ln = ln->next;
- }
- }
-
-
- /*--------------------------- expand the tabs ----------------------------*/
- void expand_tabs(char *buf, int max_len)
- {
- int l, k;
- char tmp[256], *p, *t;
-
- p = buf;
- t = &tmp[0];
- l = 0;
-
- while ((*p != '\x00') && (l < max_len)) {
- if (*p != '\x09') {
- *t = *p;
- t++;
- p++;
- l++;
- } else {
- p++;
- k = ((l / 8) + 1) * 8;
- for ( ; l < k ; l++) {
- *t = ' ';
- t++;
- if (l >= max_len) break;
- }
- }
- }
-
- *t = '\x00';
- strcpy(buf, tmp);
- }
-
-